﻿using TribesPSO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using System.Collections.Generic;

namespace TribesPSOTest
{


    /// <summary>
    ///This is a test class for DimensionedObjectTest and is intended
    ///to contain all DimensionedObjectTest Unit Tests
    ///</summary>
    [TestClass()]
    public class DimensionedObjectTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for Add
        ///</summary>
        [TestMethod()]
        public void AddTest()
        {
            EuclidianVector a = new EuclidianVector(new double[] { 1, 2, 3, 4, 5 }.AsEnumerable());
            EuclidianVector b = new EuclidianVector(new double[] { 15, 33, 12, 2, 32 }.AsEnumerable());
            EuclidianVector expected = new EuclidianVector(new double[] { 16, 35, 15, 6, 37 }.AsEnumerable());
            EuclidianVector actual;
            actual = EuclidianVector.Add(a, b);
            Assert.AreEqual(expected, actual);

            actual = EuclidianVector.Add(b, a);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for op_Equality
        ///</summary>
        [TestMethod()]
        public void op_EqualityTest()
        {
            //Test non reference equality
            EuclidianVector a = new EuclidianVector(new double[] { 5, 1, 7, 348, 3 }.AsEnumerable());
            EuclidianVector b = new EuclidianVector(new double[] { 5, 1, 7, 348, 3 }.AsEnumerable());
            bool expected = true;
            bool actual;
            actual = (a == b);
            Assert.AreEqual(expected, actual);

            //non reference inequality
            b = new EuclidianVector(new double[] { 5, 2, 7, 348, 3 }.AsEnumerable());
            expected = false;
            actual = (a == b);
            Assert.AreEqual(expected, actual);

            //Reference Equality
            b = a;
            expected = true;
            actual = (a == b);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for op_Equality
        ///</summary>
        [TestMethod()]
        public void op_EqualityUnequalLengthTest()
        {
            EuclidianVector a = new EuclidianVector(new double[] { 5, 1, 7, 348, 3 }.AsEnumerable());
            EuclidianVector b = new EuclidianVector(new double[] { 5, 1, 7, 348, 3, 0 }.AsEnumerable());
            bool expected = false;
            bool actual;
            actual = (a == b);
            Assert.AreEqual(expected, actual);

            actual = (b == a);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for op_Equality
        ///</summary>
        [TestMethod()]
        public void NullOp_EqualityTest()
        {
            //Test non reference equality
            EuclidianVector a = new EuclidianVector(new double[] { 5, 1, 7, 348, 3 }.AsEnumerable());
            EuclidianVector b = null;
            bool expected = false;
            bool actual;
            actual = (a == b);
            Assert.AreEqual(expected, actual);

            b = new EuclidianVector(new double[] { 5, 2, 7, 348, 3 }.AsEnumerable());
            a = null;
            actual = (a == b);
            Assert.AreEqual(expected, actual);

            b = null;
            expected = true;
            actual = (a == b);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Add
        ///</summary>
        [TestMethod()]
        public void AddUnequalTest()
        {
            EuclidianVector a = new EuclidianVector(new double[] { 1, 6, 5, 3, 34 }.AsEnumerable());
            EuclidianVector b = new EuclidianVector(new double[] { 1, 6, 5, 3, 34, 0 }.AsEnumerable());
            EuclidianVector actual;
            try
            {
                actual = EuclidianVector.Add(a, b);
                Assert.Fail("Expected to get an exeption");
            }
            catch (DimensionMismatchException) { }
            try
            {
                actual = EuclidianVector.Add(b, a);
                Assert.Fail("Expected to get an exeption");
            }
            catch (DimensionMismatchException) { }
        }

        /// <summary>
        ///A test for GetHashCode
        ///</summary>
        [TestMethod()]
        public void GetHashCodeTest()
        {
            IEnumerable<double> DimensionData = new double[] { 6, 34, 2, 7, 3, 8, 1 }.AsEnumerable();
            EuclidianVector target = new EuclidianVector(DimensionData);
            int trial1 = target.GetHashCode();
            int trial2 = target.GetHashCode();
            Assert.AreEqual(trial1, trial2);

            EuclidianVector identical = new EuclidianVector(DimensionData);
            int trial3 = target.GetHashCode();
            int trial4 = target.GetHashCode();
            Assert.AreEqual(trial3, trial4);

            EuclidianVector different = new EuclidianVector(new double[] { 6, 34, 2, 7, 3, 8, 0 }.AsEnumerable());
            int trial5 = target.GetHashCode();
            int trial6 = different.GetHashCode();
            Assert.AreNotEqual(trial5, trial6);
        }

        /// <summary>
        ///A test for Equals
        ///</summary>
        [TestMethod()]
        public void EqualsTest()
        {
            IEnumerable<double> DimensionData = new double[] { 6, 4, 21, 7, 3, 8, 0 }.AsEnumerable();
            EuclidianVector target = new EuclidianVector(DimensionData);
            EuclidianVector b = new EuclidianVector(new double[] { 6, 4, 21, 7, 3, 8, 1 }.AsEnumerable());
            bool expected = false;
            bool actual;
            actual = target.Equals(b);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for op_Inequality
        ///</summary>
        [TestMethod()]
        public void op_InequalityTest()
        {
            EuclidianVector a = new EuclidianVector(new double[] { 1, 3, 6, 8, 4, 2, 3 }.AsEnumerable());
            EuclidianVector b = new EuclidianVector(new double[] { 1, 2, 6, 7, 1, 2, 3 }.AsEnumerable());
            bool expected = true;
            bool actual;
            actual = (a != b);
            Assert.AreEqual(expected, actual);            
        }
    }
}
